/* Copyright (c) 2008 LepomisLab.com, Andrey Turkin
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "NSObjectController.h"
#include "NSArray.h"
#include "NSKeyedUnarchiver.h"

IMPLEMENT_DYNAMIC_CLASS(NSObjectController, NSController)

NSObjectController::NSObjectController() : NSController(), _content(NULL)
{
	exposeBinding(wxT("content"));
	exposeBinding(wxT("contentObject"));
	exposeBinding(wxT("selectedObjects"));
	exposeBinding(wxT("selection"));
}

void NSObjectController::initWithUnarchiver(NSKeyedUnarchiver *archiver)
{
	NSController::initWithUnarchiver(archiver);

	archiver->decodeObjectForKey(wxT("_NSManagedProxy"));
}

void NSObjectController::_setValue(const wxString& key, wxObject *value)
{
	if (key == wxT("content") || key == wxT("contentObject"))
	{
		_willValueChangedForKey(wxT("selectedObjects"));
		_content = value;
		_didValueChangedForKey(wxT("selectedObjects"));
	} else if (key == wxT("selection") || key == wxT("selectedObjects"))
	{
		wxFAIL;
	} else
		NSController::_setValue(key, value);
}

class __NS_SelectionProxy : public NSObject
{
public:
	__NS_SelectionProxy(NSObject* obj) : m_object(obj) {}

protected:
	virtual void _setValue(const wxString& key, wxObject *value)
	{
		NSObject* obj = wxDynamicCast(m_object->getValue(wxT("selectedObjects")), NSObject);
		wxASSERT(obj);
		obj->setValue(key, value);
	}

	virtual wxObject* _getValue(const wxString& key)
	{
		NSObject* obj = wxDynamicCast(m_object->getValue(wxT("selectedObjects")), NSObject);
		wxASSERT(obj);
		wxObject* w_obj =obj->getValueForKeypath(key);
		NSMutableArray* arr = wxDynamicCast(w_obj, NSMutableArray);
		if (!arr)
			return w_obj;
		switch( arr->length())
		{
		case 0:
			return NSNoSelectionMarker;
		case 1:
			return arr->getObject(0);
		default:
			return NSMultipleValuesMarker;
		}
	}

private:
	NSObject *m_object;
};

wxObject* NSObjectController::_getValue(const wxString& key)
{
	if (key == wxT("selection"))
	{
		return new __NS_SelectionProxy(this);
	} else if (key == wxT("selectedObjects"))
	{
		wxObject** a = new wxObject*[1];
		a[0] = _content;
		return new NSMutableArray(a, 1);
	} else if (key == wxT("content") || key == wxT("contentObject"))
	{
		return _content;
	} else
		return NSController::_getValue(key);
}

void NSObjectController::_willValueChangedForKey(const wxString &key)
{
	NSController::_willValueChangedForKey(key);
	if (key == wxT("selectedObjects"))
		NSController::_willValueChangedForKey(wxT("selection"));
}

void NSObjectController::_didValueChangedForKey(const wxString &key)
{
	if (key == wxT("selectedObjects"))
		NSController::_didValueChangedForKey(wxT("selection"));
	NSController::_didValueChangedForKey(key);
}
